/*
 * 版本：2.0 加入了拖拽改变透明度
 */
define(function(require, exports, module) {
	/*拖拽对象的实例化
	 * 使用Demo:
	 * //限定区域，有回调函数。
		$('#id').dragDrop({
			fixarea: [0, 100, 0, 100],
			callback: function(params) {
				$('#id').text('X:' + params.moveX + ' Y:' + params.moveY);
			}
		});
	 * 
	 * */
	$.extend({
		//获取鼠标当前坐标
		mouseCoords: function(ev) {
			if (ev.pageX || ev.pageY) {
				return {
					x: ev.pageX,
					y: ev.pageY
				};
			}
			return {
				x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
				y: ev.clientY + document.body.scrollTop - document.body.clientTop
			};
		},
		//获取样式值
		getStyle: function(obj, styleName) {
			return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj, null)[styleName];
			//				return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj,null).getPropertyValue(styleName);
		}
	});

	// 元素拖拽插件
	$.fn.dragDrop = function(options) {
		var opts = $.extend({}, $.fn.dragDrop.defaults, options);
		return this.each(function() {
			//是否正在拖动
			var bDraging = false;
			//移动的元素
			var moveEle = $(this);
			var d = $(document);

			/*透明度设置*/
			//拖拽元素原始的透明度
			var bef_opacityObj = 0;
			//透明度是否已经改变
			var is_change_opacity = 0;
			
			//判断是不是有限制区域
			var scopeObj_width = null;
			var scopeObj_height = null;
			var scopeObj_offset_top = null;
			var scopeObj_offset_left = null;
			if (opts.scopeObj != null) {
				scopeObj_width = opts.scopeObj.width();
				scopeObj_height = opts.scopeObj.height();
				scopeObj_offset_top = opts.scopeObj.offset().top;
				scopeObj_offset_left = opts.scopeObj.offset().left;
			}

			//当前移动对象的值
			var moveEle_top = null;
			var moveEle_left = null;
			var moveEle_width = null;
			var moveEle_height = null;

			//点击哪个元素，以触发移动。
			//该元素需要是被移动元素的子元素（比如标题等）
			var focuEle = opts.focuEle ? $(opts.focuEle, moveEle) : moveEle;
			if (!focuEle || focuEle.length <= 0) {
				alert('focuEle is not found! the element must be a child of ' + this.id);
				return false;
			}

			// initDiffX|Y : 初始时，鼠标与被移动元素原点的距离
			// moveX|Y : 移动时，被移动元素定位位置 (新鼠标位置与initDiffX|Y的差值)
			// 如果定义了移动中的回调函数，该对象将以参数传入回调函数。
			var dragParams = {
				initDiffX: '',
				initDiffY: '',
				moveX: '',
				moveY: ''
			};

			//点击时，记录鼠标位置
			//DOM写法： getElementById('***').onmousedown= function(event);
			focuEle.bind('mousedown', function(e) {
				if (event.preventDefault) event.preventDefault();
				else event.returnValue = false;
				e = e || window.event;
				//设置点击对象的位置
				moveEle_top = moveEle.offset().top;
				moveEle_left = moveEle.offset().left;
				moveEle_width = moveEle.width();
				moveEle_height = moveEle.height();

				bDraging = true;
				//阻止事件冒泡 
				e.stopPropagation();
				//标记开始移动

				//改变鼠标形状
				moveEle.css({
					'cursor': opts.cursorIcon == null ? 'move' : opts.cursorIcon
				});
				//捕获事件。（该用法，还有个好处，就是防止移动太快导致鼠标跑出被移动元素之外）
				//但是在google浏览器或者webkit内核的浏览器中都会说window.captureEvents()过时，将不会起任何作用，但是鼠标离开监听区域还是没问题的，即使出了浏览器
				if (moveEle.get(0).setCapture) {
					moveEle.get(0).setCapture();
				} else if (window.captureEvents) {
					window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP);
				}

				//（实际上是鼠标当前位置相对于被移动元素原点的距离）
				// DOM写法：(ev.clientX + document.body.scrollLeft - document.body.clientLeft) - document.getElementById('***').style.left;
				dragParams.initDiffX = $.mouseCoords(e).x;
				dragParams.initDiffY = $.mouseCoords(e).y;

			});

			//移动过程
			d.bind('mousemove', function(e) {
				//console.log("我在拖动啦，我已经在动了，是否要动"+bDraging);
				e = e || window.event;
				if (bDraging) {
					/*拖动的时候改变了对象的透明度，弹出之后要回到原来的透明度*/
					if (is_change_opacity == 0 && opts.opacity.is) {
						if (opts.opacity.opacityObj != null) {
							bef_opacityObj = (opts.opacity.opacityObj).css('opacity');
							is_change_opacity = 1;
							$(opts.opacity.opacityObj).css({
								opacity: opts.opacity.opacity,
							});
						}
					};
					//被移动元素的新位置，实际上鼠标当前位置与原位置之差
					//实际上，被移动元素的新位置，也可以直接是鼠标位置，这也能体现拖拽，但是元素的位置就不会精确。
					dragParams.moveX = $.mouseCoords(e).x - dragParams.initDiffX;
					dragParams.moveY = $.mouseCoords(e).y - dragParams.initDiffY;

					//	console.log(dragParams.moveX+"，"+$.mouseCoords(e).x+"，"+dragParams.initDiffX);

					//是否限定在某个区域中移动.
					//fixarea格式: [x轴最小值,x轴最大值,y轴最小值,y轴最大值]
					if (opts.fixarea) {
						if (dragParams.moveX < opts.fixarea[0]) {
							dragParams.moveX = opts.fixarea[0]
						}
						if (dragParams.moveX > opts.fixarea[1]) {
							dragParams.moveX = opts.fixarea[1]
						}

						if (dragParams.moveY < opts.fixarea[2]) {
							dragParams.moveY = opts.fixarea[2]
						}
						if (dragParams.moveY > opts.fixarea[3]) {
							dragParams.moveY = opts.fixarea[3]
						}
					}
					//console.log("还可以进来");
					//如果有设置范围对象
					if (scopeObj_width != null) {
						//console.log(scopeObj_offset_left + "," + (moveEle_left + dragParams.moveX));
						if (scopeObj_offset_left > (moveEle_left + dragParams.moveX) || scopeObj_offset_left + scopeObj_width < (moveEle_left + dragParams.moveX + moveEle_width)) {
							return;
						}
					}

					//如果有回调
					if (opts.callback) {
						//将dragParams作为参数传递
						//范围随便一个值不为空就进入
						opts.callback.call(opts.callback, dragParams);
					}

					//移动方向：可以是不限定、垂直、水平。
					if (opts.is_change) {
						if (opts.dragDirection == 'all') {
							//DOM写法： document.getElementById('***').style.left = '***px'; 
							moveEle.css({
								'left': dragParams.moveX,
								'top': dragParams.moveY
							});
						} else if (opts.dragDirection == 'vertical') {
							moveEle.css({
								'top': dragParams.moveY
							});
						} else if (opts.dragDirection == 'horizontal') {
							moveEle.css({
								'left': dragParams.moveX
							});
						}
					}
				}
			});
			//鼠标弹起时，标记为取消移动
			d.bind('mouseup', function() {
				if (bDraging == false) {
					return;
				}

				if (is_change_opacity == 1 && opts.opacity.is) {
					if (opts.opacity.opacityObj != null) {
						is_change_opacity = 0;
						$(opts.opacity.opacityObj).css({
							opacity: bef_opacityObj,
						});
					}
				};


				//阻止事件冒泡 
				bDraging = false;
				moveEle.css({
					'cursor': opts.bef_cursorIcon == null ? 'default' : opts.bef_cursorIcon
				});
				if (moveEle.get(0).releaseCapture) {
					moveEle.get(0).releaseCapture();
				} else if (window.captureEvents) {
					window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP);
				}
				//清除事件 
				document.onmousemove = null;
				document.onmouseup = null;

				//如果有回调
				if (opts.mouseupCallback) {
					//将dragParams作为参数传递
					opts.mouseupCallback.call(opts.mouseupCallback, dragParams);
				}
			});
		});
	};
	//默认配置
	$.fn.dragDrop.defaults = {
		focuEle: null, //点击哪个元素开始拖动,可为空。不为空时，需要为被拖动元素的子元素。
		callback: null, //拖动时触发的回调。
		mouseupCallback: null, //鼠标弹起的事件
		dragDirection: 'all', //拖动方向：['all','vertical','horizontal']
		fixarea: null, //限制在哪个区域拖动,以数组形式提供[minX,maxX,minY,maxY]
		cursorIcon: null, //移动时需要显示的图标  
		bef_cursorIcon:null,//移动结束之后显示的图标
		//editerObj:null //需要改改变Top Left的对象，如果没有设置的话默认是拖动对象的本身(目前还没有实现)
		is_change: true, //是否需要改变当前对象的位置，默认是需要的
		scopeObj: null, //JQ对象，当前对象移动的范围不可以操作这个区域
		opacity: {
			'is': true,
			'opacityObj': null, //拖拽是需要变透明度的对象，默认是当前对象
			'opacity': 0.5,
		},
	};
});